﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using Djs.Tools.Tresor.Properties;

namespace Djs.Tools.Tresor.Gui
{
    #region SettingForm
    public class SettingForm : SaveForm
    {
        #region Konstrukce
        public SettingForm()
            : base()
        {
            this.Init();
        }
        private void Init()
        {
            this.SavePanel.Visible = true;
            this._DataIsShown = false;
            this.Shown += new EventHandler(SettingForm_Shown);
            this.SavePanel.SaveButtonClick += new EventHandler(SavePanel_SaveButtonClick);
        }
        private void SettingForm_Shown(object sender, EventArgs e)
        {
            if (!this._DataIsShown)
            {
                this.OnDataShow();
                this._DataIsShown = true;
            }
        }
        private Point _StartPoint;
        private bool _DataIsShown;
        private void SavePanel_SaveButtonClick(object sender, EventArgs e)
        {
            this.OnDataCollect();
            this.OnDataSave();
            this.SavePanel.ContainsChange = false;
            this.FindForm().DialogResult = System.Windows.Forms.DialogResult.OK;
            if (this.SavePanel.CloseFormAfterSave)
                this.Close();
        }
        #endregion
        #region Data a události
        protected virtual void OnDataShow()
        { }
        protected virtual void OnDataCollect()
        { }
        protected virtual void OnDataSave()
        { }
        #endregion
    }
    #endregion
    #region SaveForm
    /// <summary>
    /// SaveForm má TitlePanel a StatusBar, a mezi nimi přes celou vnitřní plochu okna má DataPanel, 
    /// a dole mezi DataPanel a StatusBarem má SavePanel.
    /// </summary>
    public class SaveForm : BasicForm
    {
        #region Konstrukce
        protected override void InitCreate()
        {
            base.InitCreate();

            this.SavePanel = new SavePanel();
            this.SavePanel.Dock = DockStyle.Bottom;
            this.DataPanel = new StdPanel();
            this.DataPanel.Dock = DockStyle.Fill;
        }
        protected override void InitAddControls()
        {
            this.Controls.Add(this.DataPanel);
            this.Controls.Add(this.SavePanel);
            this.Fms.RegisterControls(this.DataPanel, this.SavePanel);

            base.InitAddControls();
        }
        [Description("Panel s daty")]
        [Category(GuiConst.CATEGORY)]
        public StdPanel DataPanel;
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        protected SavePanel SavePanel;
        #endregion
        [Description("Po uložení tlačítkem \"Uložit\" se formulář zavře. Formulář bude mít hodnotu OK.")]
        [Category(GuiConst.CATEGORY)]
        public bool CloseFormAfterSave { get { return this.SavePanel.CloseFormAfterSave; } set { this.SavePanel.CloseFormAfterSave = value; } }
        [Description("Zobrazovat SavePanel")]
        [Category(GuiConst.CATEGORY)]
        public bool SavePanelVisible { get { return this.SavePanel.Visible; } set { this.SavePanel.Visible = value; } }
        [Description("Text tlačítka \"Uložit\".")]
        [Category(GuiConst.CATEGORY)]
        public string SaveButtonText { get { return this.SavePanel.SaveButtonText; } set { this.SavePanel.SaveButtonText = value; } }
        [Description("Obrázek tlačítka \"Uložit\".")]
        [Category(GuiConst.CATEGORY)]
        public Image SaveButtonImage { get { return this.SavePanel.SaveButtonImage; } set { this.SavePanel.SaveButtonImage = value; } }
    }
    #endregion
    #region StdForm
    /// <summary>
    /// StdForm má TitlePanel a StatusBar, a mezi nimi přes celou vnitřní plochu okna má DataPanel.
    /// </summary>
    public class StdForm : BasicForm
    {
        #region Konstrukce
        protected override void InitCreate()
        {
            base.InitCreate();

            this.DataPanel = new StdPanel();
            this.DataPanel.Dock = DockStyle.Fill;
        }
        protected override void InitAddControls()
        {
            this.Controls.Add(this.DataPanel);
            this.Fms.RegisterControls(this.DataPanel);

            base.InitAddControls();
        }
        [Description("Panel s daty")]
        [Category(GuiConst.CATEGORY)]
        public StdPanel DataPanel;
        #endregion
    }
    #endregion
    #region BasicForm
    /// <summary>
    /// BasicForm má TitlePanel a StatusBar, mezi nimi nemá nic
    /// </summary>
    public class BasicForm : MoveForm
    {
        #region Konstrukce
        /// <summary>
        /// Vytvoření controlů. Nevkládat controly do this.Controls.
        /// Třída BasicForm vytváří: TitlePanel, StatusBar, StatusText.
        /// Potomek by měl nejprve volat bázovou metodu, a až poté vytvářet svoje controly.
        /// </summary>
        protected override void InitCreate()
        {
            base.InitCreate();

            this.StatusBar = new System.Windows.Forms.StatusStrip();
            this.StatusText = new System.Windows.Forms.ToolStripStatusLabel();
            this.TitlePanel = new TitlePanel();

            this.StatusBar.SuspendLayout();
            this.TitlePanel.SuspendLayout();

            this.StatusBar.Items.Add(this.StatusText);
            this.StatusBar.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
            this.StatusBar.RenderMode = System.Windows.Forms.ToolStripRenderMode.ManagerRenderMode;
            this.StatusBar.Width = DesignClientSize.Width;
            this.StatusBar.Dock = DockStyle.Bottom;

            this.TitlePanel.Dock = System.Windows.Forms.DockStyle.Top;
            this.TitlePanel.Width = DesignClientSize.Width;
            this.TitlePanel.Title = "Název okna";

            this.StatusText.Size = new System.Drawing.Size(100, 17);
            this.StatusText.Text = "Informace o okně";
        }
        /// <summary>
        /// Vložení controlů do this.Controls.
        /// Controly se s ohledem na jejich dokování vkládají ve směru odprostředka k okrajům.
        /// Třída BasicForm řeší: TitlePanel, StatusBar. Ty jsou dokovány k okrajům.
        /// Potomkové, kteří vkládají controly doprostřed, mají nejprve vložit svoje controly a teprve poté volat base.InitAddControls().
        /// Nejprve se vkládá control, který je dokován jako Fill, až po něm Top nebo Bottom. Jako poslední se vkládá Statusbar a/nebo Toolbar.
        /// Pokud potomek chce, aby jeho controly mohly sloužit k přesouvání formuláře,musí je zaregistrovat: 
        /// this.Fms.RegisterControls(vyjmenovat controly);
        /// </summary>
        protected override void InitAddControls()
        {
            this.Controls.Add(this.TitlePanel);
            this.Controls.Add(this.StatusBar);
            this.Fms.RegisterControls(this.TitlePanel, this.StatusBar);
            base.InitAddControls();
        }
        /// <summary>
        /// Dokončení inicalizace, po vložení controlů do this.Controls.
        /// Před voláním této metody byla volána metoda InitSetFormProperties), která nastavila vlastnosti: ClientSize,ControlBox,FormBorderStyle.
        /// Nyní je v this metodě InitFinalize() prováděn ResumeLayout.
        /// Třída BasicForm řeší svoje panely (_TitlePanel a _StatusBar) a this.
        /// Potomek by měl nejprve dát dokončit ResumeLayout(false) a PerformLayout() na svoje controly, a až poté volat base.InitFinalize().
        /// Poslední příkaz v metodě BasicForm.InitFinalize() je this.PerformLayout() = vydaný na Form.
        /// </summary>
        protected override void InitFinalize()
        {
            this.StatusBar.ResumeLayout(false);
            this.StatusBar.PerformLayout();
            this.TitlePanel.ResumeLayout(false);
            base.InitFinalize();
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        protected TitlePanel TitlePanel;
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        protected System.Windows.Forms.StatusStrip StatusBar;
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        protected System.Windows.Forms.ToolStripStatusLabel StatusText;
        #endregion
        public override string Text { get { return ""; } set { } }
        [Description("Titulkový text")]
        [Category(GuiConst.CATEGORY)]
        public string Title { get { return (this.TitlePanel == null ? null : this.TitlePanel.Title); } set { if (this.TitlePanel != null) this.TitlePanel.Title = value; } }
        [Description("Akce po stisknutí tlačítka Close")]
        [Category(GuiConst.CATEGORY)]
        public TitlePanelCloseAction CloseAction { get { return (this.TitlePanel == null ? TitlePanelCloseAction.None : this.TitlePanel.CloseAction); } set { if (this.TitlePanel != null) this.TitlePanel.CloseAction = value; } }
        [Description("Text ve statusbaru")]
        [Category(GuiConst.CATEGORY)]
        public string StatusInfo { get { return (this.StatusText == null ? null : this.StatusText.Text); } set { if (this.StatusText != null) this.StatusText.Text = value; } }
        [Description("Ikona ve statusbaru")]
        [Category(GuiConst.CATEGORY)]
        public Image StatusImage { get { return (this.StatusText == null ? null : this.StatusText.Image); } set { if (this.StatusText != null) this.StatusText.Image = value; } }
    }
    #endregion
    #region FillForm
    public class FillForm : MoveForm
    {
        #region Konstrukce
        protected override void InitCreate()
        {
            base.InitCreate();

            this._CloseBtn = new ActiveButton();
            this._CloseBtn.ImageDown = Tresor.Properties.Resources.dialog_cancel_2_22;
            this._CloseBtn.ImageHot = Tresor.Properties.Resources.dialog_cancel_4_22;
            this._CloseBtn.ImageStd = Tresor.Properties.Resources.dialog_cancel_3_22;
            this._CloseBtn.ShowActiveBorder = false;
            this._CloseBtn.Size = new Size(29, 29);
            this._CloseBtn.TabStop = false;
            this._CloseBtn.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
            this._CloseBtn.UseVisualStyleBackColor = false;
            this._CloseBtn.Click += new System.EventHandler(this._CloseBtn_Click);

            this._FillColor1 = Color.LightBlue;
            this._FillColor2 = Color.LightSeaGreen;
            this._FillAngle = 80f;
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
            this.DoubleBuffered = true;
            this.ResizeRedraw = true;
            this.Paint += _Paint;
        }
        protected override void InitAddControls()
        {
            base.InitAddControls();

            this.Controls.Add(this._CloseBtn);
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this._CloseBtn.Location = new Point(this.ClientSize.Width - 28, -1);
        }
        private void _CloseBtn_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private Gui.ActiveButton _CloseBtn;
        #endregion
        #region Paint
        private void _Paint(object sender, PaintEventArgs e)
        {
            Rectangle area = new Rectangle(Point.Empty, this.ClientSize);
            using (LinearGradientBrush lgb = new LinearGradientBrush(area, _FillColor1, _FillColor2, _FillAngle))
            {
                e.Graphics.FillRectangle(lgb, area);
            }

            string title = this._Title;
            if (!String.IsNullOrEmpty(title))
            {
                PointF point = new PointF(6f, 7f);
                SizeF size = SizeF.Empty;
                using (Font font = new Font(this.Font.Name, 1.12f * this.Font.Size, FontStyle.Bold))
                using (SolidBrush brush = new SolidBrush(this.ForeColor))
                {
                    e.Graphics.DrawString(title, font, brush, point);
                    size = e.Graphics.MeasureString(title, font);
                }

                RectangleF line = new RectangleF(point.X, point.Y + size.Height - 2f, this.Width - 30, 1f);
                using (LinearGradientBrush lgb = new LinearGradientBrush(line, this.ForeColor, _FillColor2, 0f))
                {
                    e.Graphics.FillRectangle(lgb, line);
                }
            }
        }
        private void _Repaint()
        {
            this.Invalidate();
        }
        #endregion
        [DefaultValue(typeof(Color), "LightBlue")]
        [Description("Barva výplně počáteční")]
        [Category(GuiConst.CATEGORY)]
        public Color FillColor1 { get { return _FillColor1; } set { _FillColor1 = value; _Repaint(); } } private Color _FillColor1;
        [DefaultValue(typeof(Color), "LightSeaGreen")]
        [Description("Barva výplně koncová")]
        [Category(GuiConst.CATEGORY)]
        public Color FillColor2 { get { return _FillColor2; } set { _FillColor2 = value; _Repaint(); } } private Color _FillColor2;
        [DefaultValue(80f)]
        [Description("Barva výplně koncová")]
        [Category(GuiConst.CATEGORY)]
        public float FillAngle { get { return _FillAngle; } set { _FillAngle = value; _Repaint(); } } private float _FillAngle;
        [DefaultValue("")]
        [Description("Titulek okna")]
        [Category(GuiConst.CATEGORY)]
        public string Title { get { return _Title; } set { _Title = value; _Repaint(); } } private string _Title;
    }
    #endregion
    #region MoveForm
    /// <summary>
    /// Formulář, který se může pohybovat tažením za svoji kteroukoli část
    /// </summary>
    public class MoveForm : Form
    {
        #region Konstrukce
        public MoveForm()
        {
            this.Init();
        }
        private void Init()
        {
            this.InitCreate();
            this.InitAddControls();
            this.InitSetFormProperties();
            this.InitFinalize();
        }
        /// <summary>
        /// Vytvoření controlů. Nevkládat controly do this.Controls.
        /// Třída MoveForm řeší: Font.
        /// Potomek by měl nejprve volat bázovou metodu, a až poté vytvářet svoje controly.
        /// </summary>
        protected virtual void InitCreate()
        {
            this.Font = Control.DefaultFont.CreateSimilar(1.07f);
            this.Fms = new FormMoveSupport(this);
            this.SuspendLayout();
        }
        /// <summary>
        /// Vložení controlů do this.Controls.
        /// Controly se s ohledem na jejich dokování vkládají ve směru odprostředka k okrajům.
        /// Třída MoveForm řeší: nic.
        /// Potomkové, kteří vkládají controly doprostřed, mají nejprve vložit svoje controly a teprve poté volat base.InitAddControls().
        /// Nejprve se vkládá control, který je dokován jako Fill, až po něm Top nebo Bottom. 
        /// Jako poslední se vkládá Statusbar a/nebo Toolbar.
        /// Pokud potomek chce, aby jeho controly mohly sloužit k přesouvání formuláře,musí je zaregistrovat: 
        /// this.Fms.RegisterControls(vyjmenovat controly);
        /// </summary>
        protected virtual void InitAddControls()
        {
        }
        /// <summary>
        /// Třída Movform nastaví vlastnosti: ClientSize,ControlBox,FormBorderStyle.
        /// Volá se po vložení controlů do this.Controls, ale před InitFinalize().
        /// </summary>
        protected virtual void InitSetFormProperties()
        {
            this.ClientSize = this.DesignClientSize;
            this.ControlBox = false;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
        }
        /// <summary>
        /// Dokončení inicalizace, po vložení controlů do this.Controls.
        /// Před voláním této metody byla volána metoda InitSetFormProperties), která nastavila vlastnosti: ClientSize,ControlBox,FormBorderStyle.
        /// Nyní je v this metodě InitFinalize() prováděn ResumeLayout.
        /// Třída MoveForm řeší jen this.ResumeLayout(false) a this.PerformLayout().
        /// Potomek by měl nejprve dát ResumeLayout(false) a PerformLayout() na svoje controly, a až poté volat base.InitFinalize().
        /// Poslední příkaz v metodě MoveForm.InitFinalize() je this.PerformLayout() = vydaný na Form.
        /// </summary>
        protected virtual void InitFinalize()
        {
            this.ResumeLayout(false);
            this.PerformLayout();
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        /// <summary>
        /// Vrací velikost ClientSize okna, na kterou jsou designovány rozměry controlů v inicializaci.
        /// Pokud potomek přepíše, pak na tuto velikost reaguje i bázová třída.
        /// </summary>
        protected virtual Size DesignClientSize { get { return new Size(940, 520); } }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        protected FormMoveSupport Fms;
        #endregion
        #region Show
        /// <summary>
        /// Otevře formulář jako modální okno, na pozici kde se nachází myš
        /// </summary>
        public DialogResult ShowDialogAtCursor()
        {
            Point offset = new Point(-7, -3);
            return this.ShowDialogAtCursor(offset, null);
        }
        /// <summary>
        /// Otevře formulář jako modální okno, na pozici kde se nachází myš
        /// </summary>
        public DialogResult ShowDialogAtCursor(Point offset)
        {
            return this.ShowDialogAtCursor(offset, null);
        }
        /// <summary>
        /// Otevře formulář jako modální okno, na pozici kde se nachází myš
        /// </summary>
        public DialogResult ShowDialogAtCursor(IWin32Window owner)
        {
            Point offset = new Point(-7, -3);
            return this.ShowDialogAtCursor(offset, owner);
        }
        /// <summary>
        /// Otevře formulář jako modální okno, na pozici kde se nachází myš
        /// </summary>
        public DialogResult ShowDialogAtCursor(Point offset, IWin32Window owner)
        {
            Point mousePoint = System.Windows.Forms.Cursor.Position;
            this.StartPosition = FormStartPosition.Manual;
            this.Location = new Point(mousePoint.X + offset.X, mousePoint.Y + offset.Y);

            return this.ShowDialog(owner);
        }
        #endregion
    }
    #endregion
    #region FormMoveSupport
    /// <summary>
    /// Třída, která podporuje přesouvání formuláře za jeho tělo (a za jeho zvolené controly), nejen za titulek.
    /// Je tak možno přesouvat i formulář bez borderu.
    /// Použití: na formuláři se vytvoří instanční proměnná typu FormMoveSupport, do konstruktoru se předá hostitelský form.
    /// Tím se form (jeho vlastní plocha) stane přesouvatelná.
    /// Následně je možno zaregistrovat libovolný další control (metodou this.RegisterControl(control)),
    /// který se pak rovněž stane aktivním z hlediska přesouvání.
    /// </summary>
    public class FormMoveSupport
    {
        #region Public vrstva
        /// <summary>
        /// Konstruktor, předává se Form který se bude přesouvat.
        /// </summary>
        /// <param name="form"></param>
        public FormMoveSupport(Form form)
        {
            this._Form = form;
            this.RegisterControl(form);
        }
        /// <summary>
        /// Konstruktor, předává se Form který se bude přesouvat.
        /// Současně lze předat controly, které se mají zaregistrovat.
        /// </summary>
        /// <param name="form"></param>
        public FormMoveSupport(Form form, params Control[] controls)
        {
            this._Form = form;
            this.RegisterControl(form);

            foreach (Control control in controls)
                RegisterControl(control);
        }
        /// <summary>
        /// Registrace libovolného množství controlů.
        /// This se zaháčkuje do jeho Mouse eventů a ošetří je tak, aby bylo možno jejich přesouváním přesouvat Form.
        /// </summary>
        /// <param name="control"></param>
        public void RegisterControls(params Control[] controls)
        {
            foreach (Control control in controls)
                RegisterControl(control);
        }
        /// <summary>
        /// Registrace libovolného controlu.
        /// This se zaháčkuje do jeho Mouse eventů a ošetří je tak, aby bylo možno jejich přesouváním přesouvat Form.
        /// </summary>
        /// <param name="control"></param>
        public void RegisterControl(Control control)
        {
            control.MouseDown += new MouseEventHandler(_MouseDown);
            control.MouseMove += new MouseEventHandler(_MouseMove);
            control.MouseUp += new MouseEventHandler(_MouseUp);
        }
        #endregion
        #region Privátní vrstva
        void _MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;

            Point fp = this._Form.Location;
            Point mp = Control.MousePosition;
            Point df = new Point(mp.X - fp.X, mp.Y - fp.Y);
            this._FormToMouseOffset = df;

            Size ds = SystemInformation.DragSize;
            this._InactiveMouseArea = new Rectangle(mp.X - ds.Width / 2, mp.Y - ds.Height / 2, ds.Width, ds.Height);

            this._Notificator = sender as IFormMoveNotification;
            this._NotifyState(FormMoveNotificationState.MouseDown);
        }
        void _MouseMove(object sender, MouseEventArgs e)
        {
            if (!this._IsMouseDown) return;

            Point mp = Control.MousePosition;
            if (this._IsWaitToMove)
            {
                if (this._InactiveMouseArea.Value.Contains(mp)) return;
                this._InactiveMouseArea = null;
                this._NotifyState(FormMoveNotificationState.BeginMove);
            }

            Point df = this._FormToMouseOffset.Value;
            Point fp = new Point(mp.X - df.X, mp.Y - df.Y);
            this._Form.Location = fp;

            this._NotifyState(FormMoveNotificationState.Move);
        }
        void _MouseUp(object sender, MouseEventArgs e)
        {
            this._NotifyState((this._IsMoveForm ? FormMoveNotificationState.DoneMove : FormMoveNotificationState.MouseUp));
            this._FormToMouseOffset = null;
            this._Notificator = null;
        }
        private void _NotifyState(FormMoveNotificationState state)
        {
            if (this._HasNotificator)
                this._Notificator.FormMoveNotification(this, new FormMoveNotificationArgs(state));
        }
        private Form _Form;
        private Point? _FormToMouseOffset;
        private Rectangle? _InactiveMouseArea;
        /// <summary>
        /// Jsme ve stavu, kdy je myš stisknuta. Tato property neřeší, zda se čeká na pohyb, nebo se pohybuje.
        /// </summary>
        private bool _IsMouseDown { get { return (this._FormToMouseOffset.HasValue); } }
        /// <summary>
        /// Jsme ve stavu, kdy je myš stisknuta ale ještě se nepohnula natolik, aby to zahájilo pohyb (čekáme na pohyb)
        /// </summary>
        private bool _IsWaitToMove { get { return (this._IsMouseDown && this._InactiveMouseArea.HasValue); } }
        /// <summary>
        /// Jsme ve stavu, kdy je myš stisknuta a pohybuje se tak daleko, že to pohybuje formulářem.
        /// </summary>
        private bool _IsMoveForm { get { return (this._IsMouseDown && !this._InactiveMouseArea.HasValue); } }
        private IFormMoveNotification _Notificator;
        private bool _HasNotificator { get { return (this._Notificator != null); } }
        #endregion
    }
    #endregion
    #region interface IFormMoveNotification + Args + State
    /// <summary>
    /// Interface, skrz který může správce pohybu formuláře FormMoveSupport 
    /// předávat informace o pohybu do toho objektu, který je zprostředkovatelem pohybu.
    /// Jinými slovy: pokud máme na formuláři button, který se zaregistroval jako control který umožňuje přesouvat formulář,
    /// pak tímto interfacem bude dostávat zprávy o pohybu (zahájení, průběh, konec).
    /// </summary>
    public interface IFormMoveNotification
    {
        void FormMoveNotification(object sender, FormMoveNotificationArgs args);
    }
    /// <summary>
    /// Informace o stavu pohybu formuláře skrze FormMoveSupport
    /// </summary>
    public class FormMoveNotificationArgs
    {
        public FormMoveNotificationArgs(FormMoveNotificationState state)
        {
            this.State = state;
        }
        /// <summary>
        /// Stav procesu přesouvání (začátek, průběh, konec)
        /// </summary>
        public FormMoveNotificationState State { get; private set; }
    }
    /// <summary>
    /// Stav pohybu formuláře skrze FormMoveSupport
    /// </summary>
    public enum FormMoveNotificationState
    {
        None,
        /// <summary>
        /// Stiskla se myš, ale to ještě neznamená zahájení pohybu.
        /// </summary>
        MouseDown,
        /// <summary>
        /// Zvedla se myš, aniž by došlo k pohybu.
        /// </summary>
        MouseUp,
        /// <summary>
        /// Stisknutá myš se začala pohybovat nad rámec chvění.
        /// </summary>
        BeginMove,
        /// <summary>
        /// Probíhá přesun.
        /// </summary>
        Move,
        /// <summary>
        /// Končí přesun. Poté už nebude volána notifikace se stavem MouseUp.
        /// </summary>
        DoneMove
    }
    #endregion
}
